<!-- 图库 -->
 
<template>
	<div class="container">
		<!-- 侧边栏 -->
		<div class="sidebar">
			<div class="sidebar-main">
				<!-- 项目信息区域 -->
				<div class="custom-card custom-input">
					<span>{{project?.name || '未知项目'}}</span>
				</div>
				<div class="custom-card custom-info">
					<div 
						class="info-circle"
						:style="{ backgroundColor: currentMethodConfig?.color || '#409EFF' }"
					>
						{{ currentMethodConfig?.icon || '📊' }}
					</div>
					<div class="info-cont">
						<div class="title">
							{{ currentMethodConfig?.title || project?.instance?.title || '分类' }}
						</div>
						<div class="text">
							{{ currentMethodConfig?.description || project?.instance?.description || '' }}
						</div>
					</div>
				</div>
				<!-- 图像信息区域 -->
				<div class="custom-card custom-types">
					<div class="card-header">
						<div class="header-top">
							<div class="title" @click="handleImageCollapse">
								<el-icon>
									<component :is="showImage ? 'ArrowDown' : 'ArrowUp'"></component>
								</el-icon>
								<span>图像</span>
							</div>
							<div class="close">
								<el-icon @click="handleAddSingleImage" title="添加单张图片"><PictureFilled /></el-icon>
								<el-icon @click="handleAddFolderImages" title="从文件夹批量添加"><FolderAdd /></el-icon>
							</div>
						</div>
						<div class="header-bottom">
							<span class="title">图像 {{currentIndex + 1}}/{{project?.images?.length || 0}}</span>
						</div>
					</div>
					<!-- 只在选中图片时显示图片信息 -->
					<div class="card-body" v-if="showImage && imageInfo">
						<div class="custom-item">
							<div class="label">名称</div>
							<div class="text">{{imageInfo?.name || ''}}</div>
						</div>
						<div class="custom-item">
							<div class="label">路径</div>
							<div 
								class="text clickable-path" 
								@click="handleOpenImageFolder"
								:title="getFullImagePath()"
							>
								{{imageInfo?.path || ''}}
							</div>
						</div>
						<div class="custom-item">
							<div class="label">大小</div>
							<div class="text">{{imageInfo?.size || ''}}</div>
						</div>
						<div class="custom-item">
							<div class="label">标签实例</div>
							<div class="text">{{imageInfo?.instances || 0}}</div>
						</div>
					</div>
				</div>
				<!-- 拆分映射区域 -->
				<div 
				v-if="imageInfo"
				class="custom-card custom-change">
					<div class="card-header">
						<div class="header-top">
							<div class="title" @click="handleCollapse">
								<el-icon>
									<component :is="showCollapse?'ArrowDown' : 'ArrowUp'"></component>
								</el-icon>
								<span>拆分映射</span>
							</div>
							<div 
							class="close"
							@click="handleClose"
							>
								<el-icon><CircleCloseFilled /></el-icon>
							</div>
						</div>
						<div class="header-bottom">
							<span class="text">{{currentIndex + 1}}/{{project?.images?.length || 0}}个图像</span>
							<el-icon @click="handleDelete()" title="删除图像"><Delete /></el-icon>
						</div>
					</div>
					<div class="card-body" v-if="showCollapse">
						<!-- 图像用途分类选择 -->
						<div class="split-section">
							<div class="section-title">选择用途：</div>
							<div 
							v-for="(item,index) in splitTypes"
							:key="index"
							class="custom-btn"
							:class="{ active: imageInfo?.splitType === item.key }"
							:style="{ borderColor: item.color }"
							@click="handleChangeSplitType(item.key)"
							>
								<div class="round" :style="{ background: item.color }"></div>
								<span class="title" :style="{ color: item.color }">{{item.title}}</span>
								<span class="num">{{getTypeCount(item.key)}}</span>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>

		<!-- 主内容区域 -->
		<div class="content">
			<div 
			class="cell-box">
				<el-tooltip 
				v-for="(item,index) in project['images']"
				:key="`in-${index}`"
				placement="bottom">
					<template #content>
						<div class="custom-tip-body">
							<div class="text">标签类别：{{item['lable']}}</div>
							<div class="text">标签实例：{{item['instances']}}</div>
							<div class="text">图像：{{item['name']}}</div>
							<div class="text">路径: {{item['path']}}</div>
						</div>
					</template>
					<div 
					@click.stop="handleChange(item)"
					@dblclick="handleDetail(item)"
					class="cell"
					:class="{ active: imageInfo && item['id'] == imageInfo['id']}"
					>
						<img 
						:src="getImageUrl(item)"
						class="cell-img"
						@error="handleImageError"
						/>
						<div class="cell-title">{{item['name']}}</div>
					</div>
				</el-tooltip>
			</div>
		</div>
		<el-dialog
		    v-model="visible"
		    title="创建新项目"
		    width="700"
		  >
			<el-form 
			ref="formRef"
			label-position="top"
			:model="form"
			>
				<el-form-item 
				label="拆分名称："
				prop="name"
				:rules="Rules.name"
				>
					<el-input 
					style="width: 60%;"
					v-model="form['name']" 
					placeholder="请输入"></el-input>
				</el-form-item>
				<el-form-item label="">
					<div class="chart-box">
						<e-charts
						class="custom-chart" 
						:option="pieOption"></e-charts>
						<div class="chart-right">
							<div class="cell-header">
								<span>图像</span>
								<span>{{project['images']['length']}}</span>
							</div>
							<div class="table-header">
								<span>数…</span>
								<span>图像</span>
								<span>百分比</span>
							</div>
							<div 
							v-for="(item,index) in form['splits']"
							:key="index"
							class="table-cell">
								<div class="left">
									<div 
									:style="{background: item['color']}"
									class="circle"></div>
									<div class="title">{{item['title']}}</div>
								</div>
								<el-input-number 
								size="small" 
								v-model="item['num']"
								:min="0" 
								/>
								<el-input-number 
								size="small" 
								:min="0" 
								:max="100"
								v-model="item['percentage']" />
							</div>
						</div>
					</div>
					
				</el-form-item>
				<el-form-item label="">
					<div class="split-footer">
						<el-checkbox 
						v-model="form['checked']" 
						label="设置一个用户自定义的随机种子" />
						<el-input-number 
						v-if="form['checked']"
						size="small" 
						:min="0" 
						v-model="form['seed']" />
					</div>
				</el-form-item>
			</el-form>
			<template #footer>
			    <div class="dialog-footer">
			      <el-button plain @click="handleCancel">取消</el-button>
			      <el-button 
				  type="primary" 
				  @click="handleCreate">
			        创建拆分和应用分配
			      </el-button>
			    </div>
			</template>
		</el-dialog>
	</div>
</template>

<script setup>
	import { ElMessageBox, ElMessage } from 'element-plus'
	import {
		ref,
		onMounted,
		computed
	} from 'vue'
	import { useProjectStore } from '@store';
	import {
		useRouter
	} from 'vue-router'
	const router = useRouter()
	const projectStore = useProjectStore();
	const project = computed(() => {
		const proj = projectStore.getProject
		console.log('[Gallery] 当前项目数据:', proj)
		return proj
	})
	
	// 图像拆分类型定义
	const splitTypes = ref([
		{ key: 4, title: '未分类', color: '#909399' }, // 默认状态
		{ key: 1, title: '训练', color: '#4791FF' },
		{ key: 2, title: '验证', color: '#52C41A' },
		{ key: 3, title: '测试', color: '#7353F7' }
	])
	
	// 加载本地方法配置
	const instanceList = ref([])
	const currentMethodConfig = computed(() => {
		if (!project.value?.instance?.id || !instanceList.value.length) {
			return null
		}
		return instanceList.value.find(method => method.id === project.value.instance.id)
	})
	const showImage = ref(true)
	const imageInfo = computed(() => projectStore.getImageInfo)
	const currentImgId = computed(() => projectStore.getCurrentImgId)
	const currentIndex = computed(() => {
		const id = currentImgId.value
		const imgs = project.value?.images || []
		if(imgs.length && id){
			const cIndex = imgs.findIndex(({ id: cId }) => id == cId)
			return cIndex >= 0 ? cIndex : 0
		}
		return 0
	})
	
	// 获取指定类型的图像数量
	const getTypeCount = (type) => {
		if (!project.value?.images) return 0
		return project.value.images.filter(img => (img.splitType || 4) === type).length
	}
	const currentSplitsId = ref('')
	const showCollapse = ref(true)
	const dForm = {
		name: '',
		splits: [
			{ key: 2, title: '训练', color: '#2165F8', num: 0, percentage: 0 },
			{ key: 3, title: '验证', color: '#5AD8A6', num: 0, percentage: 0 },
			{ key: 4, title: '测试', color: '#FA8B14', num: 0, percentage: 0 }
		],
		seed: 0,
		checked: true
	}
	const form = ref({ ...dForm })
	const Rules = {
		name: [
			{ required: true, message: '请输入拆分名称', trigger: 'blur' }
		]
	}
	const pieOption = {
	  tooltip: {
		show: false
	  },
	  legend: {
		show: false
	  },
	  series: [
		{
		  name: 'Access From',
		  type: 'pie',
		  radius: ['40%', '95%'],
		  avoidLabelOverlap: false,
		  label: {
			show: false
		  },
		  emphasis: {
			label: {
			  show: false
			}
		  },
		  labelLine: {
			show: false
		  },
		  data: [
			{ value: 1048, name: 'Search Engine' },
			{ value: 735, name: 'Direct' },
			{ value: 580, name: 'Email' }
		  ],
		  color: ['#2165F8','#5AD8A6','#FA8B14']
		}
	  ]
	}
	
	const handleChange = (item) => {
		projectStore.setImageInfo(item)
		projectStore.setCurrentImg(item['id'])
	}
	const handleDetail = (item) => {
		projectStore.setImageInfo(item)
		projectStore.setCurrentImg(item['id'])
		currentSplitsId.value = item['splits'].length ? item['splits'][0]['id'] : ''
		router.push('images')
	}
	const handleImageCollapse = () => {
		showImage.value = !showImage.value
	}
	const visible = ref(false)
	const handleCollapse = () => {
		showCollapse.value = !showCollapse.value
	}
	const handleClose = () => {
		projectStore.setImageInfo(null)
	}
	// 添加单张图片功能
	const handleAddSingleImage = async () => {
		try {
			if (window.electronAPI && window.electronAPI.openImageDialog) {
				// 单选模式
				const imagePaths = await window.electronAPI.openImageDialog()
				if (imagePaths && imagePaths.length > 0) {
					await importImages(imagePaths)
				}
			} else {
				alert('系统API不可用')
			}
		} catch (error) {
			console.error('[Gallery] 添加单张图片失败:', error)
			alert('添加单张图片失败: ' + error.message)
		}
	}
	
	// 从文件夹批量添加图片功能
	const handleAddFolderImages = async () => {
		try {
			if (window.electronAPI && window.electronAPI.openDirectoryDialog) {
				const folderPath = await window.electronAPI.openDirectoryDialog()
				if (folderPath) {
					// 获取文件夹中所有图片文件
					const imagePaths = await window.electronAPI.getImagesFromFolder(folderPath)
					if (imagePaths && imagePaths.length > 0) {
						await importImages(imagePaths)
					} else {
						alert('所选文件夹中未找到支持的图片文件')
					}
				}
			} else {
				alert('系统API不可用')
			}
		} catch (error) {
			console.error('[Gallery] 批量添加图片失败:', error)
			alert('批量添加图片失败: ' + error.message)
		}
	}
	
	// 通用图像导入功能
	const importImages = async (imagePaths) => {
		// 调用项目管理器导入图像
		const result = await window.electronAPI.importImagesToProject(project.value.path, imagePaths)
		if (result.success) {
			// 更新项目中的图像列表
			result.images.forEach(imageData => {
				const imageItem = {
					id: imageData.id,
					name: imageData.filename,
					size: imageData.width && imageData.height ? `${imageData.width}*${imageData.height}` : '未知尺寸',
					instances: 0,
					path: imageData.path,
					image: imageData.path,
					splitType: 4, // 默认为未分类
					splits: []
				}
				projectStore.addImage(imageItem)
			})
			// 清理可能的重复并保存项目
			await cleanDuplicateImages()
			await projectStore.saveProject()
			console.log(`[Gallery] 成功导入 ${result.images.length} 张图像`)
			
			// 如果这是第一次导入且之前没有选中图片，选中第一张
			if (project.value?.images && project.value.images.length > 0 && !imageInfo.value) {
				const firstImage = project.value.images[0]
				projectStore.setImageInfo(firstImage)
				projectStore.setCurrentImg(firstImage.id)
			}
		} else {
			alert('导入图像失败: ' + result.error)
		}
	}
	
	// 修改图像拆分类型
	const handleChangeSplitType = async (type) => {
		if (!imageInfo.value) return
		
		try {
			// 更新图像的拆分类型
			const updatedImage = {
				...imageInfo.value,
				splitType: type
			}
			
			// 更新store中的图像信息
			projectStore.setImageInfo(updatedImage)
			
			// 更新项目中的图像列表
			const currentProject = { ...project.value }
			const imageIndex = currentProject.images.findIndex(img => img.id === imageInfo.value.id)
			if (imageIndex >= 0) {
				currentProject.images[imageIndex] = updatedImage
				projectStore.setProject(currentProject)
				// 保存项目
				await projectStore.saveProject()
				console.log(`[Gallery] 图像 ${updatedImage.name} 的类型已更改为: ${splitTypes.value.find(s => s.key === type)?.title}`)
			}
		} catch (error) {
			console.error('[Gallery] 修改图像类型失败:', error)
			alert('修改图像类型失败: ' + error.message)
		}
	}
	
	// 图像缓存
	const imageDataCache = ref(new Map())
	
	// 获取图像 URL
	const getImageUrl = (item) => {
		if (!item) {
			return getPlaceholderImage()
		}
		
		// 如果已经是完整URL，直接返回
		if (item.image && (item.image.startsWith('http') || item.image.startsWith('data:'))) {
			return item.image
		}
		
		// 检查缓存
		if (imageDataCache.value.has(item.id)) {
			return imageDataCache.value.get(item.id)
		}
		
		// 构建本地文件路径并异步加载
		if (item.path && project.value?.path) {
			const fullImagePath = `${project.value.path}/${item.path}`
			
			// 异步加载图片数据
			loadImageData(item.id, fullImagePath)
			
			// 先返回占位图，加载完成后会自动更新
			return getPlaceholderImage()
		}
		
		// 如果没有路径信息，使用占位图
		console.warn('[Gallery] 图像路径信息不完整:', item)
		return getPlaceholderImage()
	}
	
	// 异步加载图像数据
	const loadImageData = async (imageId, imagePath) => {
		try {
			if (window.electronAPI?.getLocalImageData) {
				const result = await window.electronAPI.getLocalImageData(imagePath)
				if (result.success) {
					// 使用reactive方式更新缓存，确保Vue能检测到变化
					imageDataCache.value = new Map(imageDataCache.value.set(imageId, result.data))
				} else {
					console.error('[Gallery] 加载图片失败:', result.error)
				}
			}
		} catch (error) {
			console.error('[Gallery] 加载图片数据异常:', error)
		}
	}
	
	// 获取占位图像
	const getPlaceholderImage = () => {
		return ''
	}
	
	// 图像加载错误处理
	const handleImageError = (event) => {
		console.warn('[Gallery] 图像加载失败:', event.target.src)
		// 设置默认占位图
		event.target.src = getPlaceholderImage()
	}
	
	// 获取完整图片路径
	const getFullImagePath = () => {
		if (!imageInfo.value?.path || !project.value?.path) {
			return ''
		}
		return `${project.value.path}/${imageInfo.value.path}`
	}
	
	// 打开图片所在文件夹
	const handleOpenImageFolder = async () => {
		if (!imageInfo.value?.path || !project.value?.path) {
			alert('图片路径信息不完整')
			return
		}
		
		try {
			const fullImagePath = getFullImagePath()
			const folderPath = fullImagePath.substring(0, fullImagePath.lastIndexOf('/'))
			
			if (window.electronAPI?.openFolder) {
				const result = await window.electronAPI.openFolder(folderPath)
				if (!result.success) {
					alert('打开文件夹失败: ' + result.error)
				}
			} else {
				alert('系统API不可用')
			}
		} catch (error) {
			console.error('[Gallery] 打开文件夹失败:', error)
			alert('打开文件夹失败: ' + error.message)
		}
	}
	const handleDelete = () => {
		const msg = '该类别存在未删除的标签，是否确认删除？删除后，该类别下面的标签都会删除'
		ElMessageBox.confirm(msg, 'Warning', {
			type: 'warning',
			confirmButtonText: '确认',
			cancelButtonText: '取消',
		}).then(() => {
			const { id } = imageInfo.value
			const { images } = project.value
			const index = images.findIndex(({ id: cId }) => cId == id)
			images.splice(index,1)
			projectStore.setImageInfo(null)
			projectStore.setCurrentImg(null)
			ElMessage({
			    type: 'success',
			    message: '删除成功',
			})
		})
	}
	const formRef = ref()
	const handleCancel = () => {
		visible.value = false
		form.value = { ...dForm }
		formRef.value?.resetFields()
	}
	const handleCreate = () => {
		formRef.value?.validate((valid) => {
			if(valid){
				const splits = JSON.parse(JSON.stringify(imageInfo.value['splits']))
				const splitItem = {
					id: new Date().getTime(),
					...form.value
				}
				splits.push(splitItem)
				projectStore.setImageInfo({
					...imageInfo.value,
					splits
				})
				handleCancel()
			}
		})
	}
	// 更新图像尺寸信息
	const updateImageDimensions = async () => {
		if (!project.value?.images || !window.electronAPI?.getImageDimensions) {
			return
		}
		
		let updated = false
		const currentProject = { ...project.value }
		
		for (let i = 0; i < currentProject.images.length; i++) {
			const image = currentProject.images[i]
			
			// 检查是否需要更新尺寸（如果size是固定的1024*1024或未知尺寸）
			if (!image.size || image.size === '1024*1024' || image.size === '未知尺寸') {
				try {
					const fullImagePath = `${project.value.path}/${image.path}`
					const result = await window.electronAPI.getImageDimensions(fullImagePath)
					
					if (result.success && result.size) {
						currentProject.images[i] = {
							...image,
							size: result.size
						}
						updated = true
					}
				} catch (error) {
					console.warn(`[Gallery] 无法获取图片尺寸: ${image.name}`, error)
				}
			}
		}
		
		if (updated) {
			projectStore.setProject(currentProject)
			await projectStore.saveProject()
		}
	}
	
	// 清理重复图像数据
	const cleanDuplicateImages = async () => {
		if (!project.value?.images) return
		
		const currentProject = { ...project.value }
		const uniqueImages = []
		const seenIds = new Set()
		const seenPaths = new Set()
		
		currentProject.images.forEach(img => {
			if (!seenIds.has(img.id) && !seenPaths.has(img.path)) {
				uniqueImages.push(img)
				seenIds.add(img.id)
				seenPaths.add(img.path)
			} else {
				console.log(`[Gallery] 移除重复图像: ${img.name}`)
			}
		})
		
		if (uniqueImages.length !== currentProject.images.length) {
			currentProject.images = uniqueImages
			projectStore.setProject(currentProject)
			await projectStore.saveProject()
		}
	}
	
	onMounted(async () => {
		// 加载本地方法配置
		try {
			if (window.electronAPI?.getLocalMethods) {
				const result = await window.electronAPI.getLocalMethods()
				if (result.success && result.config) {
					instanceList.value = result.config.methods || []
				}
			}
		} catch (error) {
			console.error('[Gallery] 加载方法配置失败:', error)
		}
		
		// 清理重复数据
		await cleanDuplicateImages()
		
		// 更新现有图片的真实尺寸
		await updateImageDimensions()
		
		// 默认选中第一张图片（如果存在）
		if (project.value?.images && project.value.images.length > 0) {
			const firstImage = project.value.images[0]
			projectStore.setImageInfo(firstImage)
			projectStore.setCurrentImg(firstImage.id)
		}
	})
</script>

<style scoped lang="scss">
.container {
	.sidebar {
		display: flex;
		flex-direction: column;
		padding: 0 0 23px 15px;
		background: transparent;
		border: 0;
		border-radius: 0;
		.sidebar-main{
			display: flex;
			flex-direction: column;
			gap: 10px;
			.custom-card{
				background: linear-gradient( 180deg, rgba(255,255,255,0.6) 0%, rgba(255,255,255,0.4) 100%);
				border-radius: 6px;
				border: 2px solid #FFFFFF;
				padding: 0;
				.card-header{
					width: 100%;
					cursor: pointer;
					padding: 10px 14px;
					.header-top{
						position: relative;
						display: flex;
						align-items: center;
						justify-content: space-between;
						.title{
							display: flex;
							align-items: center;
							gap: 8px;
							cursor: pointer;
							span{
								font-size: 14px;
								color: #333;
							}
						}
						.close{
							display: flex;
							align-items: center;
							gap: 10px;
						}
					}
					.header-bottom{
						display: flex;
						margin-top: 10px;
						align-items: center;
						justify-content: space-between;
						.title{
							font-size: 14px;
							color: #333;
						}
						.text{
							font-size: 12px;
							color: #606266;
						}
					}
				}
				.card-body{
					padding: 0 14px 14px;
					.card-text{
						font-size: 12px;
						color: #606266;
					}
				}
			}
			.custom-input{
				height: 50px;
				display: flex;
				align-items: center;
				justify-content: space-between;
				padding: 0 15px;
				span{
					font-size: 14px;
					color: #222;
					font-weight: 600;
				}
			}
			.custom-types{
				.card-body{
					display: flex;
					flex-direction: column;
					gap: 10px;
					.custom-item{
						display: flex;
						flex-direction: column;
						gap: 8px;
						.label{
							font-size: 14px;
							color: #333333;
						}
						.text{
							font-size: 12px;
							color: #606266;
							white-space: wrap;
							word-break: break-all;
						}
					}
					
				}
			}
			.custom-change{
				.card-body{
					display: flex;
					flex-direction: column;
					gap: 20px;
					.split-section {
						display: flex;
						flex-direction: column;
						gap: 15px;
						
						.section-title {
							font-size: 14px;
							color: #333;
							font-weight: 500;
							margin-bottom: 5px;
						}
					}
					
					.custom-btn{
						display: flex;
						align-items: center;
						justify-content: space-between;
						border-width: 2px;
						border-style: solid;
						border-radius: 8px;
						height: 40px;
						padding: 0 12px;
						gap: 10px;
						cursor: pointer;
						margin-bottom: 8px;
						transition: all 0.2s ease;
						background: rgba(255,255,255,0.8);
						
						&:hover {
							background: rgba(255,255,255,0.95);
							transform: translateX(2px);
						}
						
						&.active {
							background: rgba(255,255,255,1);
							box-shadow: 0 2px 8px rgba(0,0,0,0.1);
							border-width: 3px;
						}
						
						.round{
							width: 12px;
							height: 12px;
							border-radius: 50%;
							background: #2165F8;
						}
						.title{
							font-size: 13px;
							color: #2165F8;
							font-weight: 500;
						}
						.num{
							margin-left: auto;
							font-size: 14px;
							font-weight: 600;
							min-width: 20px;
							text-align: center;
						}
					}
				}
			}
			
			// 可点击路径样式
			.clickable-path {
				cursor: pointer;
				color: #409EFF !important;
				text-decoration: underline;
				
				&:hover {
					color: #66b1ff !important;
				}
			}
		}
	}
	.content{
		display: flex;
		flex-direction: column;
		.cell-box{
			display: flex;
			flex-flow: wrap;
			gap: 20px;
			.cell{
				border-radius: 10px;
				width: 150px;
				height: 180px; // 固定卡片总高度
				background: #fff;
				display: flex;
				flex-direction: column;
				cursor: pointer;
				border: 2px solid #fff;
				box-sizing: border-box;
				box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
				transition: box-shadow 0.2s ease, transform 0.2s ease;
				
				&:hover {
					box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
					transform: translateY(-2px);
				}
				.cell-img{
					border-radius: 8px 8px 0 0;
					width: 100%;
					height: 150px; // 固定图片区域高度
					object-fit: cover; // 保持比例，裁剪多余部分
					background: #e5e5e5;
					display: block;
					transition: transform 0.2s ease;
				}
				
				&:hover .cell-img {
					transform: scale(1.02);
				}
				.cell-title{
					font-size: 12px;
					color: #222;
					height: 30px;
					width: 100%;
					display: flex;
					align-items: center;
					padding: 0 8px;
					box-sizing: border-box;
					white-space: nowrap;
					overflow: hidden;
					text-overflow: ellipsis;
				}
			}
			.active{
				border: 2px solid #2165F8;
				position: relative;
				.cell-title{
					color: #2165F8;
				}
			}
			.active::before{
				position: absolute;
				right: -4px;
				top: -4px;
				z-index: 2;
				width: 16px;
				height: 16px;
				content: '✔';
				font-size: 10px;
				color: #fff;
				background: #2165F8;
				border-radius: 50%;
				display: flex;
				align-items: center;
				justify-content: center;
			}
		}
		
	}
}

.chart-box{
	display: flex;
	flex-flow: nowrap;
	gap: 50px;
	.custom-chart{
		height: 160px;
		width: 160px;
	}
	.chart-right{
		min-width: 260px;
		.cell-header{
			display: flex;
			justify-content: space-between;
			span{
				font-size: 14px;
				color: #333333;
			}
		}
		.table-header{
			display: grid;
			grid-template-columns: repeat(3,1fr);
			align-items: center;
			background: rgba(0,0,0,0.04);
			border-radius: 6px;
			span{
				text-align: center;
				font-size: 10px;
				height: 30px;
				line-height: 30px;
				color: #606266;
			}
		}
		.table-cell{
			display: grid;
			grid-template-columns: repeat(3,1fr);
			align-items: center;
			justify-content: center;
			.left{
				display: flex;
				align-items: center;
				gap: 6px;
				.circle{
					width: 9px;
					height: 9px;
					border-radius: 50%;
				}
				.title{
					font-size: 10px;
					color: #8C8C8C;
				}
			}
		}
	}
}
.split-footer{
	display: flex;
	align-items: center;
	gap: 20px;
}
.el-input-number--small{
	--el-fill-color-light: #fff;
	width: 80px;
}
.dialog-footer{
	display: flex;
	align-items: center;
	justify-content: center;
}

// 项目信息区域样式
.custom-info {
	display: flex;
	align-items: center;
	gap: 10px;
	height: 80px;
	padding: 0 15px;
	
	.info-circle{
		width: 35px;
		height: 35px;
		border-radius: 50%;
		background: #409EFF;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 18px;
		color: white;
		text-shadow: 0 1px 2px rgba(0,0,0,0.2);
	}
	
	.info-cont {
		flex: 1;
		
		.title {
			font-size: 14px;
			color: #333;
			margin-bottom: 4px;
		}
		
		.text {
			font-size: 12px;
			color: #666;
		}
	}
}
</style>